package com.general.client.widgets.autopositionpanel;

//import static com.hp.f8upper.client.utils.jquery.JQ.JQ;

import java.util.Iterator;

import com.general.client.basewidget.BaseWidget;
import com.general.client.widgets.autopositionpanel.PositioningLogic.Position;
import com.general.client.widgets.autopositionpanel.PositioningLogic.VerticalPosition;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.HasAllFocusHandlers;
import com.google.gwt.event.dom.client.HasAllKeyHandlers;
import com.google.gwt.event.dom.client.HasAllMouseHandlers;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.dom.client.MouseWheelHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Focusable;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.InsertPanel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.PopupPanel.PositionCallback;
//import com.hp.f8upper.client.utils.jquery.JqueryNative.CallBack;
//import com.hp.f8upper.common.client.widgets.BaseWidget;
//import com.hp.f8upper.common.client.widgets.Widget48Display;
//import com.hp.f8upper.common.client.widgets.hoverpanel.PositioningLogic.Position;
//import com.hp.f8upper.common.client.widgets.hoverpanel.PositioningLogic.VerticalPosition;

public class AutoPositionPanel extends BaseWidget implements InsertPanel, HasWidgets,
		HasAllMouseHandlers, HasClickHandlers, HasAllKeyHandlers, HasAllFocusHandlers, Focusable {

	@UiTemplate("AutoPositionPanel.ui.xml")
	interface AutoPositionPanelUiBinder extends UiBinder<Widget, AutoPositionPanel> {
	}

	public static AutoPositionPanelUiBinder uiBinder = GWT.create(AutoPositionPanelUiBinder.class);

	@UiField
	PopupPanel popupPanel;

	@UiField
	FocusPanel hoverPanel;

	@UiField
	FlowPanel container;

	private VerticalPosition defaultVerticalPosition = VerticalPosition.BELOW;

	private boolean inited = false;

	public AutoPositionPanel() {
		init();
	}

	private Widget relativeWidget;

	private boolean isWidthAsRelativeWidget;

	public void setRelativeWidget(Widget relativeWidget) {
		this.relativeWidget = relativeWidget;
	}

	private void init() {
		if (inited)
			return;
		initWidget(uiBinder.createAndBindUi(this));

		popupPanel.hide();
		hoverPanel.setVisible(false);

		inited = true;
	}

	public HandlerRegistration addBlurHandler(BlurHandler blurHandler) {
		return hoverPanel.addBlurHandler(blurHandler);
	}

	@Override
	public void setVisible(boolean visible) {
		if (visible) {
//			JQ(hoverPanel.getElement()).fadeIn(200);
			hoverPanel.setVisible(true);
			setPanelPosition();
		} else {
			hoverPanel.setVisible(false);
			popupPanel.hide();
//			JQ(hoverPanel.getElement()).fadeOut(200, new CallBack() {
//
//				@Override
//				public void onCall() {
//					popupPanel.hide();
//				}
//			});
		}
	}

	@Override
	public boolean isVisible() {
		return hoverPanel.isVisible() && popupPanel.isShowing();
	}

	public VerticalPosition getDefaultVerticalPosition() {
		return defaultVerticalPosition;
	}

	public void setDefaultVerticalPosition(VerticalPosition defaultVerticalPosition) {
		this.defaultVerticalPosition = defaultVerticalPosition;
	}

	public void isWidthAsRelativeWidget(boolean isWidthAsRelativeWidget) {
		this.isWidthAsRelativeWidget = isWidthAsRelativeWidget;

	}

	private void setPanelPosition() {

		popupPanel.setPopupPositionAndShow(new PositionCallback() {

			@Override
			public void setPosition(int old_offsetWidth, int old_offsetHeight) {
				PositioningLogic positioningLogic = new PositioningLogic();
				Position position =
						positioningLogic.getPosition(hoverPanel, relativeWidget, 0, 0, defaultVerticalPosition);
				if (isWidthAsRelativeWidget) {
					int width = relativeWidget.getElement().getOffsetWidth();
					popupPanel.setWidth(width + "px");
				} else {
					popupPanel.setWidth("auto");
				}
				popupPanel.setPopupPosition(position.absX, position.absY);
			}
		});
	}

	private class CloseCommand implements Command {

		@Override
		public void execute() {
			setVisible(false);
		}

	}

	private void addCloseAction(Widget w) {
		if (w instanceof CanCloseHoverPanel) {
			((CanCloseHoverPanel) w).close(new CloseCommand());
		}
	}

	public void setFocus(boolean focused) {
		hoverPanel.setFocus(focused);
	}

	/************* InsertPanel methods *************/
	@Override
	public void add(Widget w) {
		addCloseAction(w);
		container.add(w);
	}

	@Override
	public void insert(Widget w, int beforeIndex) {
		addCloseAction(w);
		container.insert(w, beforeIndex);
	}

	@Override
	public Widget getWidget(int index) {
		return container.getWidget(index);
	}

	@Override
	public int getWidgetCount() {
		return container.getWidgetCount();
	}

	@Override
	public int getWidgetIndex(Widget child) {
		return container.getWidgetIndex(child);
	}

	@Override
	public boolean remove(int index) {
		return container.remove(index);
	}

	@Override
	public void clear() {
		container.clear();
	}

	@Override
	public Iterator<Widget> iterator() {
		return container.iterator();
	}

	@Override
	public boolean remove(Widget w) {
		return container.remove(w);
	}

	@Override
	public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
		return hoverPanel.addMouseDownHandler(handler);
	}

	@Override
	public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
		return hoverPanel.addMouseUpHandler(handler);
	}

	@Override
	public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
		return hoverPanel.addMouseOutHandler(handler);
	}

	@Override
	public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) {
		return hoverPanel.addMouseOverHandler(handler);
	}

	@Override
	public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
		return hoverPanel.addMouseMoveHandler(handler);
	}

	@Override
	public HandlerRegistration addMouseWheelHandler(MouseWheelHandler handler) {
		return hoverPanel.addMouseWheelHandler(handler);
	}

	@Override
	public HandlerRegistration addClickHandler(ClickHandler handler) {
		return hoverPanel.addClickHandler(handler);
	}

	@Override
	public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) {
		return hoverPanel.addKeyUpHandler(handler);
	}

	@Override
	public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) {
		return hoverPanel.addKeyDownHandler(handler);
	}

	@Override
	public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) {
		return hoverPanel.addKeyPressHandler(handler);
	}

	@Override
	public HandlerRegistration addFocusHandler(FocusHandler handler) {
		return hoverPanel.addFocusHandler(handler);
	}

	@Override
	public int getTabIndex() {
		return hoverPanel.getTabIndex();
	}

	@Override
	public void setAccessKey(char key) {
		hoverPanel.setAccessKey(key);
	}

	@Override
	public void setTabIndex(int index) {
		hoverPanel.setTabIndex(index);

	}
	
	@Override
	public void addStyleName(String style) {
		hoverPanel.addStyleName(style);
	}

}
